#include "WMI_Reader.h"
#include "wmi_hresult.h"

using namespace std;

WMI_HResult* 
WMI_Reader::initConnection()
{
	WMI_ConnectionManager* wmiMng = new WMI_ConnectionManager();
	WMI_HResult* whres = wmiMng->initCOMSecurityConfiguration();

	whres = wmiMng->createConnection(PC_LOCAL_USER, PC_LOCAL_PASSWORD, PC_NAMESPACE_REG, registryConnection);	
	whres = wmiMng->createConnection(PC_LOCAL_USER, PC_LOCAL_PASSWORD, PC_NAMESPACE, wmiConnection);	

	return whres;
}

WMI_HResult* 
WMI_Reader::initConnection(wstring user, wstring pass, wstring host)
{
	WMI_ConnectionManager* wmiMng = new WMI_ConnectionManager();
	WMI_HResult* whres = wmiMng->initCOMSecurityConfiguration();

	whres = wmiMng->createConnection(user, pass, host, PC_NAMESPACE_REG,registryConnection);	
	whres = wmiMng->createConnection(user, pass, host, PC_NAMESPACE, wmiConnection);	

	return whres;
}

WMI_HResult* 
WMI_Reader::getRootDirectories(WMI_Result<WMI_Disk>& result)
{
	wstring res;
	res.append(L"SELECT * FROM Win32_LogicalDisk");

	WMI_HResult* whres = wmiConnection.executeQuery(res.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmiConnection.getIEnumWbemClassObject();

    result.fillVector(pEnumerator);
    
    return whres;
}

WMI_HResult*
WMI_Reader::getFiles(wstring path,WMI_Result<WMI_FileDirectory> & resultD)
{
	wstring resD;
	wstring resF;
    vector<wstring> tokens;

    wstring str(path);
	
	WMI_Utils::tokenize(str, tokens, DELIMITER);
    resultD.setParent(tokens[tokens.size()-1]);
    vector<wstring>::iterator the_iterator = tokens.begin();
    bool first = true;

    while( the_iterator != tokens.end() )
    {	
        if( first)
        {
            first = false;
            resD.append(L"SELECT * FROM Win32_Directory WHERE Path = '");
			resF.append(L"SELECT * FROM CIM_DataFile WHERE Path = '");
        }
        else
        {
            resD.append(DOUBLE_SLASH);
            resD.append(*the_iterator);
			resF.append(DOUBLE_SLASH);
            resF.append(*the_iterator);
        }
        ++the_iterator;
    }

    resD.append(FINAL_DOUBLE_SLASH);    
	resF.append(FINAL_DOUBLE_SLASH);    

	resD.append(L"AND Drive='");
	resD.append(tokens[0]);
	resD.append(QUOTE);

	resF.append(L"AND Drive='");
	resF.append(tokens[0]);
	resF.append(QUOTE);

	WMI_HResult* whres = wmiConnection.executeQuery(resD.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumeratorD = NULL;
	pEnumeratorD = wmiConnection.getIEnumWbemClassObject();
	resultD.fillVector(pEnumeratorD);
    
    whres = wmiConnection.executeQuery(resF.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumeratorF = NULL;
	pEnumeratorF = wmiConnection.getIEnumWbemClassObject();
	resultD.fillVector(pEnumeratorF);
    
    return whres;
}


WMI_Result<WMI_Process>* 
WMI_Reader::getProccesses()
{
    WMI_HResult* whres = wmiConnection.executeQuery(L"SELECT * FROM Win32_Process");
    if( FAILED(whres->getHRESULT()))
    {
        delete whres;
        return 0;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmiConnection.getIEnumWbemClassObject();
   
    WMI_Result<WMI_Process>* resProc = new WMI_Result<WMI_Process>();
	resProc->fillVector(pEnumerator);
    
    
    delete whres;
	return resProc;	
}

WMI_HResult* 
WMI_Reader::getProccesses(WMI_Result<WMI_Process> &listProccesses)
{
	WMI_HResult* whres = wmiConnection.executeQuery(L"SELECT * FROM Win32_Process");
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmiConnection.getIEnumWbemClassObject();
   
	listProccesses.fillVector(pEnumerator);
    
    return whres;
}

WMI_Result<WMI_Share>* 
WMI_Reader::getShares()
{		
    WMI_HResult* whres = wmiConnection.executeQuery(L"SELECT * FROM Win32_Share");
    if( FAILED(whres->getHRESULT()))
    {
        delete whres;
        return 0;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmiConnection.getIEnumWbemClassObject();
   
    WMI_Result<WMI_Share>* res = new WMI_Result<WMI_Share>();
	res->fillVector(pEnumerator);
    
	return res;	
}

WMI_HResult* 
WMI_Reader::getShares(WMI_Result<WMI_Share> &listShares)
{
	WMI_HResult* whres = wmiConnection.executeQuery(L"SELECT * FROM Win32_Share");
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmiConnection.getIEnumWbemClassObject();
   
	listShares.fillVector(pEnumerator);

    return whres;
}

void 
WMI_Reader::getRegistryChildren(wstring path, WMI_Result<WMI_Registry>& registry)
{	
	WMI_RegistryManager man(&registryConnection);
 	WMI_Registry* rclass=new WMI_Registry();
	
	man.getRegistrys(R_LOCAL_MACHINE, path, &rclass);
	registry.setWRegistry(rclass);
}

int 
WMI_Reader::closeConnection()
{
	wmiConnection.close();
	registryConnection.close();

	return 0;
}

void
WMI_Reader::getStandardRegistryHives(WMI_Result<WMI_Registry>& standarRegistrys)
{
	std::vector<WMI_Registry>* res = new std::vector<WMI_Registry>();
	WMI_RegistryManager man(&registryConnection);
	man.getStandardRegistryHives(*res);

	WMI_Registry* rclass = new WMI_Registry();

	for(std::vector<WMI_Registry>::iterator i = res->begin(); i != res->end(); i++)
		rclass->addRegistry(&(*i));

	standarRegistrys.setWRegistry(rclass);
}
